/**
 * 
 */
package edu.byu.nlp.pipes;


import com.google.common.base.Function;
import com.google.common.base.Predicate;

/**
 * @author robbie
 *
 */
public class PipeFactories {
	
	private PipeFactories() { }
	
	public static <IL, ID, OL, OD> PipeFactory<IL, ID, OL, OD> transformingPipeFactory(
			final Function<Instance<IL, ID>, Instance<OL, OD>> f) {
		return new AbstractStatelessPipeFactory<IL, ID, OL, OD>() {

			@Override
			public Pipe<IL, ID, OL, OD> createPipe() {
				return Pipes.transformingPipe(f);
			}
		};
	}
	
	public static <L, ID, OD> PipeFactory<L, ID, L, OD> dataTransformingPipeFactory(final Function<? super ID, OD> f) {
		return transformingPipeFactory(Instances.<L, ID, OD>dataFunction(f));
	}
	
	public static <IL, D, OL> PipeFactory<IL, D, OL, D> labelTransformingPipeFactory(final Function<? super IL, OL> f) {
		return transformingPipeFactory(Instances.<IL, D, OL>labelFunction(f));
	}

	public static <L, D> PipeFactory<L, D, L, D> sourceTransformingPipeFactory(final Function<String, String> f) {
		return transformingPipeFactory(Instances.<L, D>sourceFunction(f));
	}
	
	public static <L, D> PipeFactory<L, D, L, D> filteringPipeFactory(final Predicate<Instance<L, D>> predicate) {
		return new AbstractStatelessPipeFactory<L, D, L, D>() {

			@Override
			public Pipe<L, D, L, D> createPipe() {
				return Pipes.filteringPipe(predicate);
			}
		};
	}
	
	public static <L, D> PipeFactory<L, D, L, D> dataFilteringPipeFactory(final Predicate<D> predicate) {
		return filteringPipeFactory(Instances.<L, D>dataPredicate(predicate));
	}
	
	public static <L, D> PipeFactory<L, D, L, D> labelFilteringPipeFactory(final Predicate<L> predicate) {
		return filteringPipeFactory(Instances.<L, D>labelPredicate(predicate));
	}

	public static <L, D> PipeFactory<L, D, L, D> sourceFilteringPipeFactory(final Predicate<String> predicate) {
		return filteringPipeFactory(Instances.<L, D>sourcePredicate(predicate));
	}

	public static <IL, ID, OL, OD> PipeFactory<IL, ID, OL, OD> oneToMany(final OneToManyInstanceFunction<IL, ID, OL, OD> f) {
		return new AbstractStatelessPipeFactory<IL, ID, OL, OD>() {

			@Override
			public Pipe<IL, ID, OL, OD> createPipe() {
				return Pipes.oneToMany(f);
			}
		};
	}

}
